package com.young.ums.service.impl;

import com.young.common.util.CommonUtil;
import com.young.common.core.dal.service.IDataAccessService;
import com.young.common.util.IPUtil;
import com.young.common.util.Page;
import com.young.common.util.StringUtils;
import com.young.interfaces.log.annotation.Log;
import com.young.ums.model.LoginLog;
import com.young.ums.model.LoginStatVO;
import com.young.ums.model.SsoSession;
import com.young.ums.model.enums.ELoginLogResultEnum;
import com.young.ums.service.ILoginLogService;
import com.young.ums.util.UmsConstants;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
* 登录日志服务实现
* Created by imrookie on 2018-9-21.
*/
@Service("loginLogService")
public class LoginLogServiceImpl implements ILoginLogService {

    @Resource(name = "dataAccessService")
    IDataAccessService dataAccessService;//数据层服务

    private static final Logger logger = LoggerFactory.getLogger(LoginLogServiceImpl.class);

    private static final String MAPPER = "com.young.ums.mapper.loginLog";//mapper的namespace

    //获取数据列表
    @Log("查询登录日志列表")
    @Override
    public List<LoginLog> getList(LoginLog obj) {
        return dataAccessService.getList(MAPPER + ".getList", obj);
    }

    //获取数据列表(分页)
    @Log("分页查询登录日志")
    @Override
    public List<LoginLog> getPage(LoginLog obj, Page page) {
        return dataAccessService.getList(MAPPER + ".getList", obj, page);
    }

    //查询单条
    @Log("查询登录日志")
    @Override
    public LoginLog get(String id) {
        return dataAccessService.getObject(MAPPER + ".get", id);
    }

    //统计数量
    @Log("统计登录日志数量")
    @Override
    public int count(LoginLog obj) {
        return dataAccessService.getObject(MAPPER + ".count", obj);
    }

    /**
     * 统计用户的登录次数
     *
     * @param account 登录账号
     * @return
     */
    @Log("统计用户的登录次数")
    @Override
    public long countByAccount(String account) {
        LoginLog obj = new LoginLog();
        obj.setAccount(account);
        return this.count(obj);
    }

    //修改
    @Override
    public int update(LoginLog obj) {
        return dataAccessService.update(MAPPER + ".update", obj);
    }

    //批量删除
    @Log("批量删除登录日志")
    @Override
    public int delete(String[] idArr) {
        int i = 0;
        for(String id : idArr){
            i += this.delete(id);
        }
        return i;
    }

    //删除单条
    @Override
    public int delete(String id) {
        return dataAccessService.delete(MAPPER + ".delete", id);
    }

    //插入
    @Log("插入登录日志")
    @Override
    public int insert(LoginLog obj) {
        return dataAccessService.insert(MAPPER + ".insert", obj);
    }

    //批量插入
    @Log("批量插入登录日志")
    @Override
    public int batchInsert(List<LoginLog> list) {
        int i = 0;
        for(LoginLog item : list){
            i += this.insert(item);
        }
        return i;
    }

    /**
     * 登录次数趋势统计
     *
     * @param startTime   开始时间
     * @param endTime     结束时间
     * @param loginResult 登录结果
     * @param account     账号
     * @return
     */
    @Log("登录次数趋势统计")
    @Override
    public List<LoginStatVO> statLoginNumTrend(Date startTime, Date endTime, Boolean loginResult, String account) {
        LoginLog loginLog = new LoginLog();
        loginLog.setLoginTime(startTime);
        loginLog.setLoginTime2(endTime);
        if (loginResult != null) {
            loginLog.setResult(loginResult.booleanValue() ? ELoginLogResultEnum.YES.type : ELoginLogResultEnum.NO.type);
        }
        if (StringUtils.isNotBlank(account)) {
            loginLog.setAccount(account);//账号
        }
        return dataAccessService.getList(MAPPER + ".statLoginNumTrend", loginLog);
    }

    /**
     * 写入登录日志
     *
     * @param account    账号
     * @param result     登录结果,UmsConstants.LoginLogResult
     * @param remark     说明
     * @param clientIp   客户端ip
     * @param ssoSession 会话对象
     */
    @Log("写入登录日志")
    @Override
    public void writeLoginLog(String account, String result, String remark, String clientIp, SsoSession ssoSession) {
        LoginLog loginLog = new LoginLog();
        loginLog.setId(CommonUtil.getUUID());
        if (StringUtils.isNotBlank(account) && account.length() > 32) {//登录失败,则尝试解密账号,避免密文太长存储不进去
            logger.info("[记录登录日志] 账号长度过长,截取账号前32位记录,账号={}", account);
            account = account.substring(0, 32);
        }
        loginLog.setAccount(account);
        loginLog.setResult(result);
        loginLog.setClientIp(clientIp);
        if (ssoSession != null){
            loginLog.setServerIp(ssoSession.getServerIp());
            loginLog.setDeviceType(ssoSession.getDeviceType());
            loginLog.setLoginTime(ssoSession.getSignTime());
        }else{
            loginLog.setServerIp(IPUtil.getLocalIp());
            loginLog.setDeviceType("");
            loginLog.setLoginTime(new Date());
        }
        loginLog.setRemark(remark);
        logger.debug("[记录登录日志] 插入登录日志:{}", loginLog);
        this.insert(loginLog);
    }

}